import path from 'node:path';
import axios from 'axios';
import common from 'mv-common';
import { spawn, ChildProcess } from 'child_process';
import { SDK_PATH, PRINT_SERVICES_SDK_NAME } from '../constance';

class PrinterSDK {
    #childProcess: ChildProcess | null = null;
    #request = axios.create({ baseURL: 'http://127.0.0.1:3688' });
    public verifyTimeList = [100, 500, 1000, 2000];

    public get appPath() {
        return SDK_PATH;
    }

    public get printerServicesName() {
        const extname = path.extname(PRINT_SERVICES_SDK_NAME);
        return PRINT_SERVICES_SDK_NAME.replace(extname, '');
    }

    public closeServer() {
        return this.#request
            .delete('/api/system/close', { timeout: 500 })
            .catch((e) => e);
    }

    public async closeAppServices() {
        return new Promise((resolve) => {
            common
                .isActiveProcessByName(this.printerServicesName)
                .then((isActive) => {
                    if (!isActive) return resolve(true);
                    this.closeServer().finally(() => {
                        common.killProcessName(this.printerServicesName);
                        resolve(true);
                    });
                })
                .catch(() => {
                    this.closeServer().finally(() => resolve(true));
                });
        }).then((value) => {
            this.#childProcess = null;
            return value;
        });
    }

    public async startAppServices() {
        return new Promise((resolve) => {
            this.closeAppServices().finally(() => {
                this.#childProcess = spawn(this.appPath);
                this.verifyPrintStatus(0).then((status) => {
                    if (!status) this.#childProcess = null;
                    return resolve(status);
                });
            });
        });
    }

    public verifyPrintStatus(index: number = 0) {
        return new Promise((resolve) => {
            if (!this.verifyTimeList[index]) return resolve(false);
            const timer = setTimeout(() => {
                clearTimeout(timer);
                this.#request
                    .get('/', { timeout: 500 })
                    .then((res) => {
                        if (!res.data || res.status !== 200)
                            throw new Error(res.data);
                        resolve(true);
                    })
                    .catch(() => resolve(this.verifyPrintStatus(index + 1)));
            }, this.verifyTimeList[index]);
        });
    }

    public async run() {
        return this.startAppServices();
    }
}

export default new PrinterSDK();
